﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using UTSDAL.LINQSQL.Model;
using UTSDAL.LINQSQL.Helper;
using System.Data.Linq;
using System.ComponentModel.DataAnnotations;

namespace UTSDAL.LINQSQL.Validator
{
    public class GenericValidator<E> where E:class
    {

        private UTSDataContext context = DataContextHelper.Context;

        public Expression<Func<E, bool>> getLambaKey(Object fieldName, Object fieldValue)
        {

            var parameter = Expression.Parameter(typeof(E), "e");
            var propId = Expression.Property(parameter, typeof(E).GetProperty((String)fieldName));

            return Expression.Lambda<Func<E, bool>>(Expression.Equal(propId, Expression.Constant(fieldValue)), parameter);
        }


        public String getKeyProperty()
        {
            String primaryKeyFieldName = typeof(E).Name + "Id";
            return primaryKeyFieldName;
        }


        public Expression<Func<E, bool>> getLambaKey(Guid id)
        {

            var parameter = Expression.Parameter(typeof(E), "e");
            var propId = Expression.Property(parameter, typeof(E).GetProperty(getKeyProperty()));

            return Expression.Lambda<Func<E, bool>>(Expression.Equal(propId, Expression.Constant(id)), parameter);
        }

        
        
        public Boolean doesFieldExist(string fieldName, string fieldValue, Guid primaryKeyFieldValue, ChangeAction action)
        {
            Boolean exists = false;
            
            if(action.Equals(ChangeAction.Insert))
            {
                exists = (context.GetTable<E>().Count<E>(getLambaKey(fieldName,fieldValue))>0);
                
            }

            if (action.Equals(ChangeAction.Update))
            {
                E record = context.GetTable<E>().Where<E>(getLambaKey(fieldName, fieldValue)).SingleOrDefault(getLambaKey(primaryKeyFieldValue));

                exists = record != null;

            }

            return exists;
        }


        public Boolean validate(String fieldName, String fieldValue, Guid primaryKeyFieldValue, ChangeAction action)
        {
            Boolean valid = true;

            String message = "";

            if (action.Equals(ChangeAction.Insert))
            {
                valid = (context.GetTable<E>().Count<E>(getLambaKey(fieldName, fieldValue)) == 0);
            }

            /*
            if (action.Equals(ChangeAction.Update))
            {
                E record = context.GetTable<E>().Where<E>(getLambaKey(fieldName, fieldValue)).SingleOrDefault(getLambaKey(primaryKeyFieldValue));

                valid = record != null;

            }
             */


            if (!valid)
            {
                message = " A record with " + fieldName + " " + fieldValue + " already exists in the database.... Please enter a different " + fieldName;
                throw new ValidationException(message);
            }

            return valid;
        }
    }
}
